package programs.statement;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

import game.Ship;
import be.kuleuven.cs.som.annotate.Basic;
import be.kuleuven.cs.som.annotate.Immutable;
import programs.expression.implementedClasses.Variable;
import programs.expression.superClasses.Expression;
import programs.expression.superClasses.ExpressionType;

public class IfThenElse extends ComposedStatement {

	private Expression condition;
	private Statement thenStatement;
	private Statement elseStatement;
	
	public IfThenElse(Expression condition, Statement thenStatement, Statement elseStatement) {
		this.condition = condition;
		this.thenStatement = thenStatement;
		this.elseStatement = elseStatement;
	}

	public Expression getCondition() {
		return condition;
	}
	
	@Override @Immutable
	public int getNbOfSubStatements() {
		return 2;
	}

	@Basic
	public Statement getThenStatement() {
		return this.thenStatement;
	}

	@Basic
	public Statement getElseStatement() {
		return this.elseStatement;
	}
	
	@Override
	public Set<Variable> getVariables(){
		Set<Variable> set = super.getVariables();
		set.addAll(getCondition().getVariables());
		return set;
	}

	@Override
	public boolean isValidStatement() {
		return getCondition().isValidExpression() && (getCondition().getReturnType() == ExpressionType.BOOLEAN) && 
				getThenStatement().isValidStatement() &&  getElseStatement().isValidStatement();
	}
	
	@Override
	public void setExecuter(Ship executer) {
		super.setExecuter(executer);
		getCondition().setExecuter(executer);
	}
	
	@Override
	public void assignGlobalVariable(Variable variable) {
		super.assignGlobalVariable(variable);
		condition = condition.assignGlobalVariable(variable);
	}

	@Override
	public List<Statement> getAllSubStatements() {
		List<Statement> list = new ArrayList<Statement>();
		list.add(getThenStatement());
		list.add(getElseStatement());
		return list;
	}
	
	@Override
	public Iterator<BasicStatement> getIterator() {
		return new Iterator<BasicStatement>()  {

		private Iterator<BasicStatement> currentIterator;
	
		{
			if((Boolean) getCondition().getValue())
				this.currentIterator = getThenStatement().getIterator();
			else
				this.currentIterator = getElseStatement().getIterator();
		}
	
		public boolean hasNext() {
			return currentIterator.hasNext();
		}

		public BasicStatement next() throws NoSuchElementException {
			if(!hasNext())
				throw new NoSuchElementException();
			return currentIterator.next();
		}

		public void remove() throws UnsupportedOperationException {
			throw new UnsupportedOperationException();
		}
	};
	}
}
